import time
from datetime import datetime, timezone, timedelta
from django.http import HttpResponse
import requests
import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import base64
import concurrent.futures

from HelloWorld.SimpleCache import SimpleCache

BAIDU_AK = "3BkVX4uAgWxk6wYIG2G1lg9t4ZzzLHg2"
CITY = "广州市"
ROAD_NAMES = ["市桥二桥", "沙湾大桥", "西樵大桥", "南沙大道", "番禺大道南", "广珠路"]
# 配置项
CONGESTION_KEYWORDS = ['拥堵', '缓慢']  # 可扩展

def getBusDetail(type, icon, title, stationName, lineId, stationId, targetOrder):
    url = "https://web.chelaile.net.cn/api/bus/line!encryptedLineDetail.action?s=h5&wxs=wx_app&sign=1&h5RealData=1&v=3.10.43&src=weixinapp_cx&ctm_mp=mp_wx&vc=1&cityId=040&favoriteGray=1&userId=okBHq0Gbv0AMMnBFKQ9mXXpASXG0&h5Id=okBHq0Gbv0AMMnBFKQ9mXXpASXG0&unionId=oSpTTjgMNPh3l6Hdtl6fOkChvMG4&accountId=&secret=&lat=23.124629974365234&lng=113.36199188232422&geo_lat=23.124629974365234&geo_lng=113.36199188232422&gpstype=wgs&geo_type=wgs&scene=1089&lineId={}&targetOrder={}&stationId={}&grey_city=0&stats_referer=search_result&stats_act=switch_stn&cshow=busDetail&localCityId=040&permission=0&cryptoSign=ababc1b7f381a5f440f4b2400e6314c0".format(
        lineId, targetOrder, stationId)

    headers = {
        "Referer": "https://servicewechat.com/wx71d589ea01ce3321/717/page-frame.html"
    }
    response = requests.get(url, headers=headers)

    if response.status_code == 200:
        data = response.content
        data = data.strip(b'**YGKJ').strip(b'YGKJ##')
        # 解码为字符串
        data_str = data.decode('utf-8')
        # 解析为JSON
        json_data = json.loads(data_str)
        # 打印JSON数据
        encryptResult = json_data['jsonr']['data']['encryptResult']
        # 解码
        key = b"FF32AE65FBFD19414EAAFF6291A54B42"  # 密钥，确保它是bytes类型
        # 密钥长度检查（可选）
        assert len(key) in [16, 24, 32], "Invalid key size"
        # 解码Base64密文为字节串
        cipher_text_bytes = base64.b64decode(encryptResult)
        # 创建一个AES cipher对象，使用ECB模式（不推荐用于安全敏感的应用）
        cipher = AES.new(key, AES.MODE_ECB)
        # 解密密文
        decrypted_bytes = cipher.decrypt(cipher_text_bytes)
        # 去除填充（如果使用了PKCS7填充）
        decrypted_text = unpad(decrypted_bytes, AES.block_size)
        # 输出解密后的文本（假设是UTF-8编码）
        decodeResult = json.loads(decrypted_text.decode('utf-8'))
        result = ""
        distanceToWaitStnList = []
        travelTimeList = []
        for bus in reversed(decodeResult['buses']):
            if bus['distanceToWaitStn'] > 0:
                distanceToWaitStnList.append(bus['distanceToWaitStn'])
            if len(bus['travels']) > 0:
                tip = bus['travels'][0]
                if 'recommTip' in tip.keys():
                    result += tip['recommTip'].strip() + " "
                if 'travelTime' in tip.keys():
                    if tip['travelTime'] >= 0:
                        travelTimeList.append(tip['travelTime'])
        distanceToWaitStn = "{:.2f}".format(min(distanceToWaitStnList) * 0.001) if len(
            distanceToWaitStnList) > 0 else "0.00"
        totalSecond = min(travelTimeList) if len(travelTimeList) > 0 else -1
        minutes = totalSecond // 60  # 使用整除运算符获取整数分钟数
        seconds = totalSecond % 60  # 使用取模运算符获取剩余的秒数

        content = '''
                <li>
                  <a class="emoji">{icon}</a>
                  <div>
                    <div class="name">{title}</div>
                    <div class="details">
                        {result}
                    </div>
                  </div>
                  <div class="actions">
                    <a class="{busClass}">{stationName}</a>
                  </div>
                </li> 
            '''
        busClass = ""
        if totalSecond == 0:
            stationName = fixedSpace(
                fixedSpace("") + "<br>" + fixedSpace(str("上车车啦")) + "  " + "<br>" + fixedSpace(
                    str("•")) + " " + fixedSpace(str("")) + " ")
            busClass = "A-bus"
        if totalSecond > 0:
            stationName = fixedSpace(
                fixedSpace(stationName) + "<br>" + fixedSpace(str(distanceToWaitStn)) + "公里" + "<br>" + fixedSpace(
                    str(minutes)) + "分" + fixedSpace(str(seconds)) + "秒")
            busClass = "W-bus"
        if totalSecond < 0:
            stationName = fixedSpace(
                fixedSpace("") + "<br>" + fixedSpace(str("没车车啦")) + "  " + "<br>" + fixedSpace(
                    str("•")) + " " + fixedSpace(str("")) + " ")
            busClass = "N-bus"
        content = content.replace("{icon}", icon).replace("{title}", title).replace("{result}", fixedSpace(
            result if result != "" else "")).replace("{stationName}", stationName).replace("{busClass}",
                                                                                           fixedSpace(busClass))
        return type + "|" + content

    else:
        return "请求失败"


def thread(argsList, roadInfo, weatherInfo):
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = [executor.submit(getBusDetail, **args) for args in argsList]
        concurrent.futures.wait(futures)
        results = [future.result() for future in futures]
        goList = []
        backList = []
        for result in results:
            res = result.split("|")
            type = res[0].strip()
            content = res[1].strip()
            if type in "go":
                goList.append(content)
            if type in "back":
                backList.append(content)
        goContent = '''
                    <ul id="go-content" class="tab-list">
                        {content}
                    </ul>
                '''
        backContent = '''
                    <ul id="back-content" class="tab-list">
                       {content}
                    </ul>
                '''
        goContent = goContent.replace("{content}", "".join(goList))
        backContent = backContent.replace("{content}", "".join(backList))

        head = '''
            <head>
              <meta name="viewport" content="initial-scale=1, maximum-scale=1.2, user-scalable=no">
            </head>
        '''
        tabContainer = '''
            <div class="tab-container">
                <div class="buttonContain">
                    <button class="tab-button active" onclick="changeTab(0)">🧱 上班搬砖方向</button>
                    <button class="tab-button" onclick="changeTab(1)">🏡 回家躺床方向</button>
                </div>
                <li>
                  <a class="emoji">🚦</a>
                  <div>
                    <div class="name">路况</div>
                    <div class="details">{roadInfo}</div>
                  </div>
                  <div class="actions">
                    <a class="W-bus">{weatherInfo}</a>
                  </div>
                </li> 
                <div class="tab-content">
                    {content}
                </div>
              </div>
        '''
        tabContainer = tabContainer.replace('{roadInfo}', roadInfo)
        tabContainer = tabContainer.replace('{weatherInfo}', weatherInfo)
        body = tabContainer.replace(' {content}', goContent + backContent)
        style = '''
            <style>
                .tab-container {

                }

                .buttonContain {
                  display: flex;
                  justify-content: center;
                  align-items: center;
                }

                .tab-button {
                  font-size: 1.3em;
                  display: inline-block;
                  padding: 5px;
                  border: 2px solid #DDA0DD;
                  border-radius: 10px;
                  margin: 5px;
                  color: #DDA0DD;
                  background-color: #FFFFFF;
                  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.15);
                }

                .tab-button.active {
                  background-color: #DDA0DD;
                  color: #FFFFFF;    
                  animation: tab-button-active 0.5s forwards;
                }
                
                @keyframes tab-button-active {
                  100% {
                    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
                  }
                }

                .tab-content {
                  margin-top: 10px;
                }

                .tab-list {
                  display: none;
                }

                .tab-list.active {
                  display: block;
                }

                ul {
                  list-style-type: none;
                  margin: 0;
                  padding: 0;
                }

                li {
                  display: flex;
                  align-items: center;
                  padding: 10px;
                  margin: 10px;
                  box-shadow: 1px 6px 15px rgba(221, 160, 221, 0.15);
                  border-radius: 10px;
                }

                .emoji {
                  font-size: 1.6em;
                  margin-right: 8px;
                }

                .name {
                  color: #BA55D3;
                  font-size: 1.2em;
                  font-weight: bold;
                }

                .details {
                  font-size: 1.1em;
                  font-weight: bold;
                  margin-top: 5px;
                  color: #888;
                }

                .actions {
                  margin-left: auto; /* 将操作按钮推至右侧 */
                  display: flex;
                  justify-content: center;
                }

                .W-bus {
                  width: 110px;
                  font-size: 1em;
                  font-weight: bold;
                  margin-left: 10px;
                  padding: 5px; /* 设置内边距为等宽 */
                  color: #DDA0DD;
                  text-decoration: none;
                  border-radius: 10px;
                  text-align: center;
                  box-sizing: border-box; /* 将内边距包含在按钮宽度内 */
                  justify-content: center; /* 水平居中按钮内容 */
                  align-items: center; /* 垂直居中按钮内容 */
                  box-shadow: 1px 3px 6px rgba(221, 160, 221, 0.45);
                }
                
                .A-bus {
                  width: 110px;
                  font-size: 1.2em;
                  font-weight: bold;
                  margin-left: 10px;
                  padding: 5px; /* 设置内边距为等宽 */
                  color: #FFFFFF;
                  background-color: #DDA0DD;
                  text-decoration: none;
                  border-radius: 10px;
                  text-align: center;
                  box-sizing: border-box; /* 将内边距包含在按钮宽度内 */
                  justify-content: center; /* 水平居中按钮内容 */
                  align-items: center; /* 垂直居中按钮内容 */
                  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
                }
                
                
                .N-bus {
                  color: #D8BFD8;
                  width: 110px;
                  font-size: 1em;
                  font-weight: bold;
                  margin-left: 10px;
                  padding: 5px; /* 设置内边距为等宽 */
                  text-decoration: none;
                  border-radius: 10px;
                  text-align: center;
                  box-sizing: border-box; /* 将内边距包含在按钮宽度内 */
                  justify-content: center; /* 水平居中按钮内容 */
                  align-items: center; /* 垂直居中按钮内容 */
                  box-shadow: 1px 3px 6px rgba(221, 160, 221, 0.45);
                }
            
                
                .fade-out {
                  position: relative;
                  top: 7%; /* 将数字位置设置在容器的顶部 */
                  animation: gradientFadeOut 1.2s forwards; /* 渐变消失动画 */
                }

                @keyframes gradientFadeOut {
                  0% {
                    font-size: 0.9em;
                    font-weight: bold;
                    color: transparent;
                  }

                  50% {
                    color: #BA55D3;
                  }

                  100% {
                    top:0;
                    font-size: 1em;
                  }
                }
              </style>
        '''
        script = '''
        <script>

            const htmlEntities = {
              '&lt;': '<',
              '&gt;': '>',
              '&amp;': '&',
              '&quot;': '"',
              '&apos;': "'",
              '&nbsp;': ' ',
              // 添加其他需要的实体编码映射
            };

            function changeTab(tabIndex) {
              var tabButtons = document.getElementsByClassName("tab-button");
              var tabLists = document.getElementsByClassName("tab-list");

              for (var i = 0; i < tabButtons.length; i++) {
                tabButtons[i].classList.remove("active");
                tabLists[i].classList.remove("active");
              }

              tabButtons[tabIndex].classList.add("active");
              tabLists[tabIndex].classList.add("active");
            }
            var now = new Date();
            var currentHour = now.getHours();

            if (currentHour <= 12) {
              changeTab(0);
            } else {
              changeTab(1)
            }

            function goContentDifferences(oldContent, newContent) {
              var output = '';
              for (var i = 0; i < oldContent.length || i < newContent.length; i++) {
                if (oldContent.charAt(i) !== newContent.charAt(i) && notIncludeStr(newContent.charAt(i))) {
                  output += '<span class="fade-out">' + (newContent.charAt(i) || '') + '</span>';
                } else {
                  output += (newContent.charAt(i) || '');
                }
              }
              console.log(output);
              document.getElementById('go-content').innerHTML = output;
              setTimeout(function() {
                document.getElementById('go-content').innerHTML = newContent;
              }, 4800);
            }

            function backContentDifferences(oldContent, newContent) {
              var output = '';
              var regex = '/A|W|N/';
              for (var i = 0; i < oldContent.length || i < newContent.length; i++) {
                if (oldContent.charAt(i) !== newContent.charAt(i) && notIncludeStr(newContent.charAt(i))) {
                  output += '<span class="fade-out">' + (newContent.charAt(i) || '') + '</span>';
                } else {
                  output += (newContent.charAt(i) || '');
                }
              }
              document.getElementById('back-content').innerHTML = output;
              setTimeout(function() {
                document.getElementById('back-content').innerHTML = newContent;
              }, 4800);
            }

        function notIncludeStr(str) {
          if (str == '<' || str == '>' || str == 'A' || str == 'W' || str == 'N') {
            return false;
          } else {
            return true;
          }

          if (decodedStr !== str) {
            return false;
          } else {
            return true;
          }
        }
        function replaceHTMLEntities(text) {
          return text.replaceAll(/&[a-zA-Z]+;/g, (entity) => {
            return htmlEntities[entity] || entity;
          });
        }
          // 定义局部刷新函数
          function refreshContent() {
            fetch(window.location.href)  // 替换为您要刷新的页面的 URL
              .then(response => response.text())
              .then(data => {
              var parser = new DOMParser();
                var doc = parser.parseFromString(data, "text/html");
                var goNewContent = doc.getElementById("go-content").innerHTML;
                var goOldContent = document.getElementById("go-content").innerHTML.replaceAll('<span class="fade-out">', "").replaceAll("</span>", "").replaceAll(/&[a-zA-Z]+;/g, (entity) => {return htmlEntities[entity] || entity;});
                goContentDifferences(goOldContent,goNewContent);

                var doc = parser.parseFromString(data, "text/html");
                var backNewContent = doc.getElementById("back-content").innerHTML;
                var backOldContent = document.getElementById("back-content").innerHTML.replaceAll('<span class="fade-out">', "").replaceAll("</span>", "").replaceAll(/&[a-zA-Z]+;/g, (entity) => {return htmlEntities[entity] || entity;});
                backContentDifferences(backOldContent,backNewContent);
              })
              .catch(error => {
                console.log("Error:", error);
              });
          }
          // 设置定时器，每隔一定时间执行局部刷新函数
          var refreshInterval = setInterval(refreshContent, 6000);  // 每6秒刷新一次
        </script>
        '''
        html = head + body + style + script
        executor.shutdown()
        return html


def fixedSpace(string):
    return string.rjust(200)


def hello(request):
    roadInfo = ''
    weatherInfo = ''
    idle = 0
    notIdleRoadInfoList = []
    if SimpleCache.get('topInfo') is None:
        try:
            # 处理所有道路
            for road in ROAD_NAMES:
                road_info = get_road_status(road, CITY, BAIDU_AK)
                if not road_info:
                    continue  # 跳过失败请求
                # 判断逻辑
                is_congested = any(kw in road_info for kw in CONGESTION_KEYWORDS)
                is_idle = 0 if is_congested else 1
                idle += is_idle
                if is_idle == 0:
                    notIdleRoadInfoList.append(f"{road_info}")  # 添加道路名称便于识别
            print('请求百度API')
        except Exception as e:
            print(e)
            roadInfo = '暂无路况信息'
        try:
            # 天气api
            weatherUrl = "https://api.map.baidu.com/weather/v1/?district_id=440115&data_type=all&ak=3BkVX4uAgWxk6wYIG2G1lg9t4ZzzLHg2"
            weatherResp = requests.get(weatherUrl)
            weatherData = json.loads(weatherResp.text)
            weatherFeel = str(weatherData['result']['now']['feels_like']) + "°C "
            weatherText = weatherData['result']['now']['text'] + "<br/>"
            weatherRange = (str(weatherData['result']['forecasts'][0]['low']) + "°C~" + str(
                weatherData['result']['forecasts'][0]['high']) + "°C") + "<br/>"
            weatherHumidity = "湿度：" + str(weatherData['result']['now']['rh']) + "%"
            weatherInfo = weatherFeel + weatherText + weatherRange + weatherHumidity
        except Exception as e:
            print(e)
            weatherInfo = '暂无天气信息'
        if idle == len(ROAD_NAMES):
            roadInfo = '道路畅通'
        else:
            roadInfo = '<br/>'.join(notIdleRoadInfoList)
    else:
        topInfo = SimpleCache.get('topInfo')
        split = topInfo.split('_')
        roadInfo = split[0]
        weatherInfo = split[1]
    argsList = []
    argsList.append({"type": "go", "icon": "🫧", "title": "南沙68", "stationName": "上坭小学", "lineId": "002062006270",
                     "stationId": "020-1191", "targetOrder": "24"})
    argsList.append({"type": "go", "icon": "🐯", "title": "番143", "stationName": "太石村", "lineId": "002078056679",
                     "stationId": "020-17335", "targetOrder": "30"})
    argsList.append({"type": "go", "icon": "🐯", "title": "番150B", "stationName": "太石村", "lineId": "020-71512-1",
                     "stationId": "020-17335", "targetOrder": "12"})
    argsList.append({"type": "go", "icon": "🐯", "title": "南沙54", "stationName": "太石村", "lineId": "020-60540-1",
                     "stationId": "020-17335", "targetOrder": "46"})
    argsList.append(
        {"type": "back", "icon": "🫧", "title": "南沙68", "stationName": "区政府东门", "lineId": "002062007902",
         "stationId": "020-14787", "targetOrder": "7"})
    argsList.append(
        {"type": "back", "icon": "🫧", "title": "南沙68(快)", "stationName": "区政府东门", "lineId": "0020159850909",
         "stationId": "020-14787", "targetOrder": "5"})
    argsList.append(
        {"type": "back", "icon": "🫧", "title": "南沙65", "stationName": "区政府东门", "lineId": "002061999282",
         "stationId": "020-14787", "targetOrder": "7"})
    argsList.append(
        {"type": "back", "icon": "🐯", "title": "番143", "stationName": "区政府东门", "lineId": "002027080767",
         "stationId": "020-14787", "targetOrder": "20"})
    argsList.append(
        {"type": "back", "icon": "🐯", "title": "番150", "stationName": "区政府东门", "lineId": "020-71500-0",
         "stationId": "020-14787", "targetOrder": "14"})
    argsList.append(
        {"type": "back", "icon": "🐯", "title": "番150B", "stationName": "区政府东门", "lineId": "020-71512-0",
         "stationId": "020-14787", "targetOrder": "17"})
    argsList.append({"type": "back", "icon": "🐯", "title": "南沙54", "stationName": "东门分站", "lineId": "020-60540-0",
                     "stationId": "020-23469", "targetOrder": "9"})
    results = thread(argsList, roadInfo, weatherInfo)
    response = HttpResponse((results))
    if SimpleCache.get('topInfo') is None:
        info = roadInfo + "_" + weatherInfo
        SimpleCache.set('topInfo', info)
    user_agent = request.META.get('HTTP_USER_AGENT', '未提供 User-Agent')
    print("来源：" + user_agent + "\n请求时间：" + datetime.now(timezone(timedelta(hours=8))).strftime("%Y-%m-%d %H:%M:%S"))
    print("---------------------------------------------------------------------------------------")
    return response


def get_road_status(road_name, city, ak):
    """获取指定道路的交通状态"""
    url = f"https://api.map.baidu.com/traffic/v1/road?road_name={road_name}&city={city}&ak={ak}"
    try:
        response = requests.get(url, timeout=5)  # 添加超时
        response.raise_for_status()  # 检查HTTP状态码
        data = response.json()

        # 检查API返回状态码
        if data.get('status') != 0:
            print(f"道路 {road_name} 请求失败: {data.get('message')}")
            return None

        description = data.get('description', '').replace('。', '')
        return description
    except (requests.exceptions.RequestException, json.JSONDecodeError) as e:
        print(f"道路 {road_name} 请求异常: {str(e)}")
        return None

